/*
 * Yabumi, a 2d scrolling shoot-em-up game.
 * Copyright (C) 2003 Gemma Teruaki <terugen@yabumi.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 */

#include <SDL.h>
#include <stdlib.h>
#include "util.h"
#include "video.h"

SDL_Surface *screen;

SDL_Surface *Sprite_Player[3][360];
SDL_Surface *Sprite_Player_Thrust[5][360];
SDL_Surface *Sprite_Enemy[3][360];
SDL_Surface *Sprite_Enemy_Thrust[5][360];
SDL_Surface *Sprite_Musashi[3][360];
SDL_Surface *Sprite_Missile[3][360];
SDL_Surface *Sprite_Flame[3];
SDL_Surface *Sprite_Homing_Tail[3][360];
SDL_Surface *Sprite_Explosion[4];
SDL_Surface *Sprite_Smoke[2];
SDL_Surface *Sprite_Item[3];
SDL_Surface *Sprite_Background[3];
SDL_Surface *Sprite_Radar[1];
SDL_Surface *Sprite_Radar_Arrow[3][360];
SDL_Surface *Sprite_Radar_Arrow_Long[1][360];
SDL_Surface *Sprite_Radar_Item[2];
SDL_Surface *Sprite_Radar_Sight[3];
SDL_Surface *Sprite_Title[2];
SDL_Surface *Sprite_Title_Press[2];
SDL_Surface *Sprite_Title_Instruct[1];

_Camera Camera;
extern _list_header sprite_list_header;

static void Video_SDL_and_Screen_Init();
static void Video_Sprites_Init();
static SDL_Surface *Load_Sprite(char *file);
static int compare_Sprites_z_order(const _Sprite *s0, const _Sprite *s1);

void Video_Init()
{
  Video_SDL_and_Screen_Init();
  Video_Sprites_Init();
}

static void Video_SDL_and_Screen_Init()
{
  if ( SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
    exit(1);
  };
  atexit(SDL_Quit);
  Uint32 flags = SDL_SWSURFACE|SDL_DOUBLEBUF;//|SDL_FULLSCREEN;
  screen = SDL_SetVideoMode(640, 480, 16, flags);
  if ( screen == NULL ) {
    fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
    exit(1);
  };
  /* erase mouse cursor */
  SDL_ShowCursor(0);
  char *title = "Yabumi";
  char *icon = "Yabumi";
  SDL_WM_SetCaption(title, icon);
  SDL_Rect cliprect;
  cliprect.x = DISPLAY_X1;
  cliprect.y = DISPLAY_Y1;
  cliprect.w = DISPLAY_X2 - DISPLAY_X1;
  cliprect.h = DISPLAY_Y2 - DISPLAY_Y1;
  SDL_SetClipRect(screen,&cliprect);
}

static void Video_Sprites_Init()
{
  SDL_Surface *image;
  char *file;
  SDL_Rect src;
  SDL_Surface *cropimage;
  int i, j;

  file = BMP_PLAYER;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Player[i][j] = rotate(cropimage,j);
    };
  };
  
  file = BMP_PLAYER_THRUST;
  image = Load_Sprite(file);
  for ( i = 0; i < 5; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Player_Thrust[i][j] = rotate(cropimage,j);
    };
  };
  file = BMP_ENEMY;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Enemy[i][j] = rotate(cropimage,j);
    };
  };
  
  file = BMP_ENEMY_THRUST;
  image = Load_Sprite(file);
  for ( i = 0; i < 5; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Enemy_Thrust[i][j] = rotate(cropimage,j);
    };
  };
  
  file = BMP_MUSASHI;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Musashi[i][j] = rotate(cropimage,j);
    };
  };

  file = BMP_MISSILE;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Missile[i][j] = rotate(cropimage,j);
    };
  };
  
  file = BMP_FLAME;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    Sprite_Flame[i] = cropimage;
  };
  
  file = BMP_HOMING_TAIL;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Homing_Tail[i][j] = rotate(cropimage,j);
    };
  };
  
  file = BMP_EXPLOSION;
  image = Load_Sprite(file);
  for ( i = 0; i < 4; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    Sprite_Explosion[i] = cropimage;
  };
  
  file = BMP_SMOKE;
  image = Load_Sprite(file);
  for ( i = 0; i < 2; i++) {
    src.x = 0;
    src.y = 16 * i;
    src.w = image->w;
    src.h = 16;
    cropimage = crop(image, &src);
    Sprite_Smoke[i] = cropimage;
  };
  
  file = BMP_ITEM;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    Sprite_Item[i] = cropimage;
  };

  file = BMP_BACKGROUND;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    Sprite_Background[i] = cropimage;
  };
  
  file = BMP_RADAR;
  image = Load_Sprite(file);
  Sprite_Radar[0] = image;
  
  file = BMP_RADAR_ARROW;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    for ( j = 0; j < 360; j++) {
      Sprite_Radar_Arrow[i][j] = rotate(cropimage,j);
    };
  };

  file = BMP_RADAR_ARROW_LONG;
  image = Load_Sprite(file);
  for ( j = 0; j < 360; j++) {
    Sprite_Radar_Arrow_Long[0][j] = rotate(image, j);
  };


  file = BMP_RADAR_ITEM;
  image = Load_Sprite(file);
  for ( i = 0; i < 2; i++) {
    src.x = 0;
    src.y = 9 * i;
    src.w = image->w;
    src.h = 9;
    cropimage = crop(image, &src);
    Sprite_Radar_Item[i] = cropimage;
  };

  file = BMP_RADAR_SIGHT;
  image = Load_Sprite(file);
  for ( i = 0; i < 3; i++) {
    src.x = 0;
    src.y = SPRITE_WH * i;
    src.w = image->w;
    src.h = SPRITE_WH;
    cropimage = crop(image, &src);
    Sprite_Radar_Sight[i] = cropimage;
  };

  file = BMP_TITLE;
  image = Load_Sprite(file);
  for ( i = 0; i < 2; i++) {
    src.x = 0;
    src.y = 109 * i;
    src.w = image->w;
    src.h = 109;
    cropimage = crop(image, &src);
    Sprite_Title[i] = cropimage;
  };

  file = BMP_TITLE_PRESS;
  image = Load_Sprite(file);
  for ( i = 0; i < 2; i++) {
    src.x = 0;
    src.y = 24 * i;
    src.w = 143;
    src.h = 24;
    cropimage = crop(image, &src);
    Sprite_Title_Press[i] = cropimage;
  };

  file = BMP_TITLE_INSTRUCT;
  image = Load_Sprite(file);
  Sprite_Title_Instruct[0] = image;
}

static SDL_Surface *Load_Sprite(char *file)
{
  SDL_Surface *dst;
  dst = SDL_LoadBMP(file);
  if ( dst == NULL ) {
    fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
    exit(1);
  };
  Uint32 flags = SDL_SRCCOLORKEY | SDL_RLEACCEL;
  Uint32 key = SDL_MapRGB(dst->format,0,0,0);
  SDL_SetColorKey(dst, flags, key);
  dst = SDL_DisplayFormat(dst);
  if ( dst == NULL ) {
    fprintf(stderr, "Couldn't DisplayFormat %s: %s\n", file, SDL_GetError());
    exit(1);
  };
  return dst;
};

void Video_Sprites_Draw()
{
/*   qsort(Sprite, Sprite_Num, sizeof(Sprite[0]),\ */
/* 	(int(*)(const void*, const void*))compare_Sprites_z_order); */

  _list_item *list_item, *temp;
  _Sprite *sprite;

  list_item = sprite_list_header.next->next;
  while (list_item != sprite_list_header.prev) {
    sprite = &list_item->data.Sprite;
    SDL_BlitSurface(sprite->image, NULL, screen, &sprite->dest);

    list_item = list_item->next;
  };

  SDL_Flip(screen);

  list_item = sprite_list_header.next->next;
  while (list_item != sprite_list_header.prev) {
    sprite = &list_item->data.Sprite;
    SDL_FillRect(screen, &sprite->dest, 0x00000000);

    temp = list_item->next;
    Kill_item(&sprite_list_header, sprite->root);
    pfree(sprite->root);
    list_item = temp;
  };
}

static int compare_Sprites_z_order(const _Sprite *s0, const _Sprite *s1)
{
  if (s0->z_order < s1->z_order) return -1;
  if (s0->z_order == s1->z_order) return 0;
  if (s0->z_order > s1->z_order) return 1;
  return 0;
};
